package com.iatinspur.learn;

import com.iatinspur.pojo.Student;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


/**
 *
 * 30 讲解 可达性分析法【5个引用】
 *   1.强引用
 *   【2.软引用】 内存不足可能被回收  【缓存】 SoftReference类实现
 *   3.弱引用
 *   4.虚引用
 *   5.终结器引用
 *
 *   启动 设置
 *    -Xmx200 -Xms200
 */
public class Learn_27_JVM {


    public static void main(String[] args) {
        //myTest1();
        // myTest2();
        myTest3();
    }


    /**
     *  软引用 总内存不足 最大内存有余    不会清空软引用
     *  软引用 总内存不足 最大内存也不足  软引用消失
     */
    public  static void  myTest1(){
        byte[] bytes1 = new byte[1024 * 1024*100];
        SoftReference<byte[]>ref1 =new SoftReference<>(bytes1);
        bytes1=null;
        System.out.println(ref1.get());
        bytes1 = new byte[1024 * 1024*100];
        System.out.println(ref1.get());
    }


    /**
     *  软引用 总内存不足 最大内存有余    不会清空软引用
     *  软引用 总内存不足 最大内存也不足  软引用消失
     *
     *  ReferenceQueue 能记录软引用数据失效 但SoftReference没失效的对象
     *  所以refs.add(ref); 就会有
     */
    public  static void  myTest2(){
        ArrayList<SoftReference>  refs=new ArrayList<>();
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        for(int i=0; i<10; i++){
            byte[] bytes = new byte[1024 * 1024*100];
            SoftReference<byte[]>ref =new SoftReference<>(bytes,queue);
            refs.add(ref);
        }

        SoftReference<byte[]>ref = null;
        int count=0;

        while((ref=(SoftReference<byte[]>)queue.poll())!=null){
            count++;
        }

        System.out.println(count);

//        for (SoftReference softReference : refs) {
//            System.out.println(softReference.get());
//        }

    }



    public  static void  myTest3(){
        StudentCache instance = StudentCache.getInstance();
        int count=1;
        while(true){
            Student student =new Student();
            student.setId(count);
            instance.cacheStudent(student);
            count ++;
        }
    }





}


/**
 * 软引用 实现内存不足 回收
 */
class StudentCache{
    private static StudentCache cache = new StudentCache();

    private Map<Integer,SoftReference<Student>> studentRfs;

    private ReferenceQueue<Student> q;

    private class StudentRef extends SoftReference<Student> {

        private Integer _key = null;

        public StudentRef(Student referent, ReferenceQueue<? super Student> q) {
            super(referent, q);
            _key = referent.getId();
        }
    }

    private StudentCache(){
        studentRfs= new HashMap<>();
        q = new ReferenceQueue<>();
    }

    public static StudentCache getInstance(){
        return cache;
    }

    public void cacheStudent(Student student){
        cleanCache();
        StudentRef studentRef = new StudentRef(student,q);
        studentRfs.put(studentRef._key,studentRef);
        System.out.println(studentRfs.size());
    }


    private void cleanCache(){
        StudentRef ref = null;
        while((ref=(StudentRef)q.poll())!=null){
            studentRfs.remove(ref._key);
            System.out.println("清除id:"+ref._key);
        }
    }

    public Student getStudent(Integer id){
        if(studentRfs.containsKey(id)){
            return studentRfs.get(id).get();
        }
        return null;
    }

}











